#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h" // 用于同步
#include "freertos/task.h"
#include "nvs_flash.h"

// #include "console/console.h"
#include "host/ble_hs.h"
#include "host/util/util.h"
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"

#include "ble_client.h"

#define TAG "BLE_CLIENT"

// --- 配置 ---
// 要连接的目标设备名称 (必须与 Server 端匹配)
static const char *target_device_name = "ESP32S3-NIMBLE";

// 目标服务和特性的 UUID (必须与 Server 端匹配)
static const ble_uuid128_t gatt_service_uuid =
    BLE_UUID128_INIT(0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
                     0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff);
static const ble_uuid128_t gatt_char_uuid =
    BLE_UUID128_INIT(0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12,
                     0x34, 0x56, 0x78, 0x90, 0xab, 0xcd);
// -------------

// 全局变量
static uint16_t conn_handle = BLE_HS_CONN_HANDLE_NONE;
static ble_addr_t peer_addr; // 存储找到的设备地址
static bool device_found = false;
static bool connected = false;
static bool service_discovered = false;
static bool characteristic_discovered = false;

// 服务和特性的句柄范围
static uint16_t service_start_handle = 0;
static uint16_t service_end_handle = 0;
static uint16_t char_val_handle = 0; // 要读写的特性的值句柄

// 用于等待 Nimble Host 同步的信号量
static SemaphoreHandle_t ble_host_task_sem = NULL;

static uint8_t ble_addr_type;

// 前向声明
static int client_gap_event(struct ble_gap_event *event, void *arg);
static void ble_client_scan(void);
static void ble_client_connect(const ble_addr_t *addr);
static int client_gatt_disc_svc_cb(uint16_t conn_handle,
                                   const struct ble_gatt_error *error,
                                   const struct ble_gatt_svc *service,
                                   void *arg);
static int client_gatt_disc_char_cb(uint16_t conn_handle,
                                    const struct ble_gatt_error *error,
                                    const struct ble_gatt_chr *chr, void *arg);
static int client_gatt_read_cb(uint16_t conn_handle,
                               const struct ble_gatt_error *error,
                               struct ble_gatt_attr *attr, void *arg);
static int client_gatt_write_cb(uint16_t conn_handle,
                                const struct ble_gatt_error *error,
                                struct ble_gatt_attr *attr, void *arg);
static void ble_client_discover_services(uint16_t conn_handle);
static void ble_client_discover_characteristics(uint16_t conn_handle,
                                                uint16_t start_handle,
                                                uint16_t end_handle);
static void ble_client_read_char(uint16_t conn_handle, uint16_t value_handle);
static void ble_client_write_char(uint16_t conn_handle, uint16_t value_handle,
                                  const uint8_t *data, uint16_t len);

// --- GATT 回调函数 ---

// 服务发现回调
static int client_gatt_disc_svc_cb(uint16_t conn_handle_cb,
                                   const struct ble_gatt_error *error,
                                   const struct ble_gatt_svc *service,
                                   void *arg)
{
    if (error && error->status != 0)
    {
        ESP_LOGE(TAG, "Service discovery failed; status=%d", error->status);
        // 可以选择断开连接并重新扫描
        ble_gap_terminate(conn_handle_cb, BLE_ERR_REM_USER_CONN_TERM);
        return error->status;
    }

    if (!service)
    {
        ESP_LOGI(TAG, "Service discovery complete.");
        if (!service_discovered)
        {
            ESP_LOGW(TAG, "Target service not found!");
            // 可以选择断开连接
            ble_gap_terminate(conn_handle_cb, BLE_ERR_REM_USER_CONN_TERM);
        }
        else
        {
            // 服务找到后，开始发现特性
            ESP_LOGI(TAG, "Discovering characteristics for service UUID %s",
                     ble_uuid_to_str(&gatt_service_uuid.u, NULL));
            ble_client_discover_characteristics(conn_handle_cb, service_start_handle,
                                                service_end_handle);
        }
        return 0;
    }

    // 检查是否是目标服务
    if (ble_uuid_cmp(&service->uuid.u, &gatt_service_uuid.u) == 0)
    {
        ESP_LOGI(
            TAG,
            "Target service found: UUID=%s, start_handle=0x%04x, end_handle=0x%04x",
            ble_uuid_to_str(&service->uuid.u, NULL), service->start_handle,
            service->end_handle);
        service_discovered = true;
        service_start_handle = service->start_handle;
        service_end_handle = service->end_handle;
    }
    else
    {
        ESP_LOGD(TAG, "Found other service: UUID=%s",
                 ble_uuid_to_str(&service->uuid.u, NULL));
    }

    return 0;
}

// 特性发现回调
static int client_gatt_disc_char_cb(uint16_t conn_handle_cb,
                                    const struct ble_gatt_error *error,
                                    const struct ble_gatt_chr *chr, void *arg)
{
    if (error && error->status != 0)
    {
        ESP_LOGE(TAG, "Characteristic discovery failed; status=%d", error->status);
        // 可以选择断开连接并重新扫描
        ble_gap_terminate(conn_handle_cb, BLE_ERR_REM_USER_CONN_TERM);
        return error->status;
    }

    if (!chr)
    {
        ESP_LOGI(TAG, "Characteristic discovery complete.");
        if (!characteristic_discovered)
        {
            ESP_LOGW(TAG, "Target characteristic not found!");
            // 可以选择断开连接
            ble_gap_terminate(conn_handle_cb, BLE_ERR_REM_USER_CONN_TERM);
        }
        else
        {
            // 特性找到后，可以进行读写操作
            ESP_LOGI(TAG, "Target characteristic found. Reading initial value...");
            ble_client_read_char(conn_handle_cb, char_val_handle);
        }
        return 0;
    }

    // 检查是否是目标特性
    if (ble_uuid_cmp(&chr->uuid.u, &gatt_char_uuid.u) == 0)
    {
        ESP_LOGI(TAG,
                 "Target characteristic found: UUID=%s, def_handle=0x%04x, "
                 "val_handle=0x%04x, properties=0x%02x",
                 ble_uuid_to_str(&chr->uuid.u, NULL), chr->def_handle,
                 chr->val_handle, chr->properties);
        characteristic_discovered = true;
        char_val_handle = chr->val_handle; // 保存值句柄

        // 检查特性权限是否匹配 (可选，但推荐)
        if (!(chr->properties & BLE_GATT_CHR_PROP_READ))
        {
            ESP_LOGW(TAG, "Characteristic does not support READ");
        }
        if (!(chr->properties & BLE_GATT_CHR_PROP_WRITE))
        {
            ESP_LOGW(TAG, "Characteristic does not support WRITE");
        }
    }
    else
    {
        ESP_LOGD(TAG, "Found other characteristic: UUID=%s",
                 ble_uuid_to_str(&chr->uuid.u, NULL));
    }
    return 0;
}

// 读操作完成回调
static int client_gatt_read_cb(uint16_t conn_handle_cb,
                               const struct ble_gatt_error *error,
                               struct ble_gatt_attr *attr, void *arg)
{
    if (error && error->status != 0)
    {
        ESP_LOGE(TAG, "Read failed; status=%d handle=0x%04x", error->status,
                 attr ? attr->handle : 0);
        ble_gap_terminate(conn_handle_cb, BLE_ERR_REM_USER_CONN_TERM);
        return error->status;
    }

    if (attr)
    {
        ESP_LOGI(TAG, "Read successful for handle 0x%04x. Data len: %d",
                 attr->handle, OS_MBUF_PKTLEN(attr->om));
        // 打印读取到的数据 (假设是字符串)
        if (OS_MBUF_PKTLEN(attr->om) > 0)
        {
            printf("Read data: ");
            uint8_t buf[32]; // 临时缓冲区
            int read_len = OS_MBUF_PKTLEN(attr->om) < sizeof(buf)
                               ? OS_MBUF_PKTLEN(attr->om)
                               : sizeof(buf) - 1;
            os_mbuf_copydata(attr->om, 0, read_len, buf);
            buf[read_len] = '\0'; // 确保字符串结束
            printf("%s\n", buf);  // 或者使用 ESP_LOG_BUFFER_HEX / ESP_LOG_BUFFER_CHAR

            // 读取成功后，尝试写入新值
            const char *new_data = "Client says Hi!";
            ESP_LOGI(TAG, "Writing new value to characteristic...");
            ble_client_write_char(conn_handle_cb, char_val_handle,
                                  (const uint8_t *)new_data, strlen(new_data));
        }
    }
    else
    {
        ESP_LOGW(TAG, "Read complete, but no attribute data received.");
    }

    return 0;
}

// 写操作完成回调
static int client_gatt_write_cb(uint16_t conn_handle_cb,
                                const struct ble_gatt_error *error,
                                struct ble_gatt_attr *attr, void *arg)
{
    if (error && error->status != 0)
    {
        ESP_LOGE(TAG, "Write failed; status=%d handle=0x%04x", error->status,
                 attr ? attr->handle : 0);
        ble_gap_terminate(conn_handle_cb, BLE_ERR_REM_USER_CONN_TERM);
        return error->status;
    }

    ESP_LOGI(TAG, "Write successful for handle 0x%04x", attr ? attr->handle : 0);

    // 写入成功后，可以断开连接或者进行其他操作
    // ESP_LOGI(TAG, "Task complete. Disconnecting...");
    // ble_gap_terminate(conn_handle_cb, BLE_ERR_CONN_TERM_LOCAL);

    return 0;
}

// --- GAP 事件处理 ---
static int client_gap_event(struct ble_gap_event *event, void *arg)
{
    struct ble_gap_conn_desc desc;
    int rc;

    switch (event->type)
    {
    case BLE_GAP_EVENT_DISC: // 扫描到设备
        // 检查广播数据中是否有设备名称
        if (event->disc.event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
            event->disc.event_type != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP)
        {
            // 只处理可连接的广播或扫描响应
            return 0;
        }

        printf("adv data: len=%d, ", event->disc.length_data);
        for (int i = 0; i < event->disc.length_data; i++)
        {
            printf("%02X", event->disc.data[i]);
        }
        printf("\n");

        struct ble_hs_adv_fields fields;
        rc = ble_hs_adv_parse_fields(&fields, event->disc.data, event->disc.length_data);
        if (rc != 0)
        {
            ESP_LOGW(TAG, "Failed to parse advertisement data");
            return 0;
        }

        // 检查设备名称是否匹配，自行修改扫描自己的设备
        // if (fields.name != NULL && fields.name_len > 0)
        // {
        //     // ESP_LOGI(TAG, "Device found: %.*s, RSSI: %d", fields.name_len,
        //     // fields.name, event->disc.rssi);
        //     if (strncmp((const char *)fields.name, target_device_name,
        //                 fields.name_len) == 0 &&
        //         fields.name_len == strlen(target_device_name))
        //     {
        //         ESP_LOGI(TAG, "Target device '%s' found, address: %s",
        //                  target_device_name, ble_addr_to_str(&event->disc.addr, NULL));

        //         // 停止扫描
        //         rc = ble_gap_disc_cancel();
        //         if (rc != 0 &&
        //             rc != BLE_HS_EALREADY)
        //         { // EALREADY 表示扫描已停止或未启动
        //             ESP_LOGE(TAG, "Failed to cancel scan; rc=%d", rc);
        //         }

        //         // 存储设备地址并尝试连接
        //         device_found = true;
        //         memcpy(&peer_addr, &event->disc.addr, sizeof(peer_addr));
        //         ble_client_connect(&peer_addr);
        //         return 0; // 找到设备，不再处理其他扫描结果
        //     }
        // }
        return 0; // 继续扫描

    case BLE_GAP_EVENT_CONNECT: // 连接事件
        if (event->connect.status == 0)
        {
            // ESP_LOGI(TAG, "Connection established to %s",
            //          ble_addr_to_str(&event->connect.conn_desc.peer_ota_addr, NULL));
            conn_handle = event->connect.conn_handle;
            connected = true;
            device_found = false; // 重置查找标志

            // 连接成功后，开始发现服务
            ble_client_discover_services(conn_handle);
        }
        else
        {
            ESP_LOGE(TAG, "Connection failed; status=%d", event->connect.status);
            // 连接失败，重新开始扫描
            if (!device_found)
            { // 如果不是因为找到设备而停止的扫描，则重新开始
                ble_client_scan();
            }
        }
        return 0;

    case BLE_GAP_EVENT_DISCONNECT: // 断开连接事件
        ESP_LOGI(TAG, "Disconnected; reason=0x%02x", event->disconnect.reason);

        // 清理状态
        conn_handle = BLE_HS_CONN_HANDLE_NONE;
        connected = false;
        service_discovered = false;
        characteristic_discovered = false;
        service_start_handle = 0;
        service_end_handle = 0;
        char_val_handle = 0;
        device_found = false; // 允许重新查找设备

        // 重新开始扫描
        ble_client_scan();
        return 0;

    case BLE_GAP_EVENT_CONN_UPDATE:
        ESP_LOGI(TAG, "Connection parameters updated.");
        return 0;

    case BLE_GAP_EVENT_ENC_CHANGE:
        ESP_LOGI(TAG, "Encryption change event; status=%d",
                 event->enc_change.status);
        return 0;

    case BLE_GAP_EVENT_MTU: // MTU 更新事件
        ESP_LOGI(TAG, "MTU updated; conn_handle=%d cid=%d mtu=%d",
                 event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value);
        return 0;

    case BLE_GAP_EVENT_SUBSCRIBE: // 处理订阅事件（如果需要）
        ESP_LOGI(TAG,
                 "Subscribe event; conn_handle=%d attr_handle=0x%04x reason=%d "
                 "prev_notify=%d cur_notify=%d prev_indicate=%d cur_indicate=%d",
                 event->subscribe.conn_handle, event->subscribe.attr_handle,
                 event->subscribe.reason, event->subscribe.prev_notify,
                 event->subscribe.cur_notify, event->subscribe.prev_indicate,
                 event->subscribe.cur_indicate);
        return 0;

    default:
        // ESP_LOGD(TAG, "Unhandled GAP event: %d", event->type);
        return 0;
    }
}

// --- BLE 控制函数 ---

// 开始扫描
static void ble_client_scan(void)
{
    struct ble_gap_disc_params disc_params;
    int rc;

    // 配置扫描参数
    disc_params.filter_duplicates = 1;                   // 过滤重复广播
    disc_params.passive = 0;                             // 主动扫描 (请求扫描响应以获取设备名称)
    disc_params.limited = 0;                             // 不限制扫描类型
    disc_params.filter_policy = BLE_HCI_SCAN_FILT_NO_WL; // 不使用白名单

    // 设置扫描间隔和窗口 (单位: 0.625ms)
    // 例如: 100ms 间隔, 50ms 窗口
    disc_params.itvl = 0x00C8;   // 160 * 0.625ms = 100ms
    disc_params.window = 0x00A0; // 80 * 0.625ms = 50ms

    ESP_LOGI(TAG, "Starting BLE scan...");
    rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &disc_params,
                      client_gap_event, NULL);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "Failed to start scan; rc=%d", rc);
        // 可能需要添加重试逻辑
    }
}

// 连接到指定地址的设备
static void ble_client_connect(const ble_addr_t *addr)
{
    int rc;
    // ESP_LOGI(TAG, "Attempting to connect to %s", ble_addr_to_str(addr, NULL));

    // 使用默认连接参数
    rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, addr, 30000, NULL, client_gap_event,
                         NULL); // 30秒超时
    if (rc != 0)
    {
        ESP_LOGE(TAG, "Failed to initiate connection; rc=%d", rc);
        // 连接启动失败，可能需要重新扫描
        ble_client_scan();
    }
}

// 发现所有服务
static void ble_client_discover_services(uint16_t conn_handle_disc)
{
    int rc;
    ESP_LOGI(TAG, "Discovering services...");
    rc = ble_gattc_disc_all_svcs(conn_handle_disc, client_gatt_disc_svc_cb, NULL);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "Failed to start service discovery; rc=%d", rc);
        // 发现失败，可以断开连接
        ble_gap_terminate(conn_handle_disc, BLE_ERR_REM_USER_CONN_TERM);
    }
}

// 发现指定服务的所有特性
static void ble_client_discover_characteristics(uint16_t conn_handle_disc,
                                                uint16_t start_handle,
                                                uint16_t end_handle)
{
    int rc;
    ESP_LOGI(TAG,
             "Discovering characteristics between handles 0x%04x and 0x%04x...",
             start_handle, end_handle);
    rc = ble_gattc_disc_all_chrs(conn_handle_disc, start_handle, end_handle,
                                 client_gatt_disc_char_cb, NULL);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "Failed to start characteristic discovery; rc=%d", rc);
        // 发现失败，可以断开连接
        ble_gap_terminate(conn_handle_disc, BLE_ERR_REM_USER_CONN_TERM);
    }
}

// 读取特性值
static void ble_client_read_char(uint16_t conn_handle_read,
                                 uint16_t value_handle)
{
    int rc;
    ESP_LOGI(TAG, "Reading characteristic value at handle 0x%04x...",
             value_handle);
    rc =
        ble_gattc_read(conn_handle_read, value_handle, client_gatt_read_cb, NULL);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "Failed to initiate read operation; rc=%d", rc);
        // 读取启动失败，可以断开连接
        ble_gap_terminate(conn_handle_read, BLE_ERR_REM_USER_CONN_TERM);
    }
}

// 写入特性值
static void ble_client_write_char(uint16_t conn_handle_write,
                                  uint16_t value_handle, const uint8_t *data,
                                  uint16_t len)
{
    int rc;
    ESP_LOGI(TAG, "Writing %d bytes to characteristic value at handle 0x%04x...",
             len, value_handle);

    // 注意: ble_gattc_write_flat 会复制数据，因此源数据可以是栈上的临时变量
    rc = ble_gattc_write_flat(conn_handle_write, value_handle, data, len,
                              client_gatt_write_cb, NULL);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "Failed to initiate write operation; rc=%d", rc);
        // 写入启动失败，可以断开连接
        ble_gap_terminate(conn_handle_write, BLE_ERR_REM_USER_CONN_TERM);
    }
}

// --- 初始化与启动 ---

// Nimble Host 同步回调
static void ble_client_on_sync(void)
{
    int rc;
    // 使用公共地址
    rc = ble_hs_id_infer_auto(0, &ble_addr_type);
    assert(rc == 0);
    uint8_t addr_val[6] = {0};
    rc = ble_hs_id_copy_addr(ble_addr_type, addr_val, NULL);
    assert(rc == 0);
    ESP_LOGI(TAG, "BLE Host synced");
    // ESP_LOGI(TAG, "BLE Host synced. Device Address: %s",
    //          ble_addr_to_str((const ble_addr_t *)addr_val, NULL));

    ble_client_scan();

    // 发送信号量，通知主任务可以开始扫描
    if (ble_host_task_sem != NULL)
    {
        xSemaphoreGive(ble_host_task_sem);
    }
}

// Nimble Host 复位回调
static void ble_client_on_reset(int reason)
{
    ESP_LOGE(TAG, "BLE Host reset; reason=%d", reason);
    // 可能需要重新初始化状态或重启设备
}

// BLE 主机任务
static void ble_host_task(void *param)
{
    ESP_LOGI(TAG, "BLE Host Task Started");
    nimble_port_run(); // 此函数不会返回，除非 nimble_port_stop() 被调用

    // 清理资源（如果 nimble_port_run 退出）
    nimble_port_freertos_deinit();
    ESP_LOGI(TAG, "BLE Host Task Stopped");
    vTaskDelete(NULL); // 删除任务自身
}

esp_err_t ble_client_init(void)
{
    esp_err_t ret;

    // // 1. 初始化 NVS (NimBLE 可能需要)
    // ret = nvs_flash_init();
    // if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
    //     ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    // {
    //     ESP_ERROR_CHECK(nvs_flash_erase());
    //     ret = nvs_flash_init();
    // }
    // ESP_ERROR_CHECK(ret);

    // 2. 初始化 NimBLE 端口
    nimble_port_init();

    // 3. 配置 NimBLE Host
    ble_hs_cfg.sync_cb = ble_client_on_sync;   // 设置同步回调
    ble_hs_cfg.reset_cb = ble_client_on_reset; // 设置复位回调
    ble_hs_cfg.store_status_cb =
        ble_store_util_status_rr; // 使用默认的状态存储回调

    // 4. 初始化 GAP 和 GATT 服务 (即使是 Client 也需要)
    ble_svc_gap_init();
    ble_svc_gatt_init();

    // 5. 设置设备名称 (可选，但有助于调试)
    ble_svc_gap_device_name_set("ESP32S3_BLE_Client");

    // 6. 配置 GATT 最大 MTU (可选)
    ret = ble_att_set_preferred_mtu(CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU);
    if (ret != 0)
    {
        ESP_LOGE(TAG, "Failed to set preferred MTU; rc=%d", ret);
        // 可以继续，但 MTU 可能不是最优的
    }

    // 创建用于同步的信号量
    ble_host_task_sem = xSemaphoreCreateBinary();
    if (ble_host_task_sem == NULL)
    {
        ESP_LOGE(TAG, "Failed to create semaphore");
        return ESP_FAIL;
    }

    return ESP_OK;
}

esp_err_t ble_client_start(void)
{
    // 启动 NimBLE Host 任务
    // nimble_port_freertos_init 会创建一个任务来运行 nimble_port_run
    nimble_port_freertos_init(ble_host_task);

    // 等待 NimBLE Host 同步完成 (通过 ble_client_on_sync 发送信号量)
    ESP_LOGI(TAG, "Waiting for BLE Host to sync...");
    if (xSemaphoreTake(ble_host_task_sem, pdMS_TO_TICKS(10000)) == pdTRUE)
    { // 等待最多 10 秒
        ESP_LOGI(TAG, "BLE Host synced. Starting scan.");
        // Host 同步后，可以开始扫描
        // 注意：启动扫描的操作现在移动到 on_sync 回调中，确保栈已准备好
        // ble_client_scan(); // 不在此处调用，在 on_sync 中调用
    }
    else
    {
        ESP_LOGE(TAG, "Timeout waiting for BLE Host sync. Cannot start scan.");
        // 可以选择停止 NimBLE 或返回错误
        nimble_port_stop();
        // nimble_port_deinit(); // 可能需要，取决于错误处理策略
        return ESP_FAIL;
    }

    return ESP_OK;
}

// 停止扫描函数
esp_err_t ble_client_stop_scan(void)
{
    int rc;

    ESP_LOGI(TAG, "Attempting to stop BLE scan...");

    // 调用 NimBLE API 停止扫描
    rc = ble_gap_disc_cancel();

    if (rc == 0)
    {
        ESP_LOGI(TAG, "Scan cancellation initiated successfully.");
        // 注意: 实际的停止会通过 BLE_GAP_EVENT_DISC_COMPLETE 事件确认
        return ESP_OK;
    }
    else if (rc == BLE_HS_EALREADY)
    {
        // EALREADY 表示扫描未在运行或已在停止过程中
        ESP_LOGW(TAG, "Scan was not running or already stopping.");
        return ESP_OK; // 从用户角度看，扫描已停止或即将停止，认为是成功
    }
    else if (rc == BLE_HS_ENOENT)
    {
        // ENOENT (NimBLE < 1.4.0 may return this instead of EALREADY if not scanning)
        ESP_LOGW(TAG, "Scan was not running.");
        return ESP_OK; // Scan is not running, goal achieved.
    }
    else
    {
        ESP_LOGE(TAG, "Failed to stop scan; rc=%d (%s)", rc, ble_hs_err_str(rc));
        return ESP_FAIL; // 返回通用失败代码
    }
}

// --- main 函数示例 (应放在你的主 c 文件中) ---
/*
#include "ble_client.h"

void app_main(void)
{
    esp_err_t ret;

    ESP_LOGI(TAG, "Starting BLE Client application...");

    ret = ble_client_init();
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "BLE Client initialization failed.");
        return;
    }

    ret = ble_client_start();
     if (ret != ESP_OK) {
        ESP_LOGE(TAG, "BLE Client start failed.");
        // 可能需要清理 ble_client_init 中分配的资源
        return;
    }

    ESP_LOGI(TAG, "BLE Client started successfully.");

    // 主任务可以继续执行其他操作，或者进入低功耗模式
    // BLE 操作将在后台的 NimBLE Host 任务中进行
    while(1) {
        vTaskDelay(pdMS_TO_TICKS(10000)); // 例如，每 10 秒打印一条消息
        // ESP_LOGI(TAG, "Main task running...");
    }
}
*/